package com.kit.personalkit.controller;

import cn.hutool.json.JSONUtil;
import com.kit.personalkit.common.JsonResponseBody;
import com.kit.personalkit.common.PageUtils;
import com.kit.personalkit.common.ResponseStatus;
import com.kit.personalkit.mapper.UserFileMapper;
import com.kit.personalkit.pojo.dto.DeleteFileByIdsDTO;
import com.kit.personalkit.pojo.dto.SearchFileByPageDTO;
import com.kit.personalkit.pojo.entity.ShareFiles;
import com.kit.personalkit.pojo.entity.UserFile;
import com.kit.personalkit.pojo.vo.UserFileVO;
import com.kit.personalkit.security.CustomUserDetails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@RestController
@RequestMapping("/files/")
public class FileController {
    private static File dir;
    /**
     * 生成项目的根目录
     */
    static {
        dir = new File("d:/fileBank");
        if (!dir.exists()){
            dir.mkdir();
        }
    }
    @Autowired(required = false)
    UserFileMapper userFileMapper;


    @PostMapping("upload")
    public JsonResponseBody uploadFile(@RequestPart("file")MultipartFile multipartFile,
                                       @AuthenticationPrincipal CustomUserDetails cud){
        if (cud==null){
            return new JsonResponseBody(ResponseStatus.NOT_LOGIN);
        }
        File userFolder = new File(dir,cud.getUserId().toString());
        if (!userFolder.exists()){
            userFolder.mkdir();
        }
        String fileName = multipartFile.getOriginalFilename();
        System.out.println(fileName);
        File dest = new File(userFolder,fileName);
        try {
            multipartFile.transferTo(dest);
            UserFile userFile = new UserFile();
            userFile.setFileName(fileName);
            userFile.setFilePath(dest.getPath());
            userFile.setFileSize(multipartFile.getSize());
            userFile.setUploadTime(new Date());
            userFile.setUserId(cud.getUserId());
            userFileMapper.insert(userFile);
            UserFileVO userFileVO = userFileMapper.selectByIdName(fileName, cud.getUserId());
            return new JsonResponseBody(ResponseStatus.UPLOAD_SUCCESS,userFileVO);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 文件列表功能
     * @return
     */
    @PostMapping("")
    public JsonResponseBody fileIndex(@RequestBody SearchFileByPageDTO form ,
                                      @AuthenticationPrincipal CustomUserDetails cud){
        if (cud == null){
            return new JsonResponseBody(ResponseStatus.NOT_LOGIN);
        }
        HashMap param = JSONUtil.parse(form).toBean(HashMap.class);
        int pageIndex = form.getPageIndex();
        int length = form.getPageSize();
        int start = (pageIndex - 1) * length;
        Integer userId = cud.getUserId();
        param.put("start",start);
        param.put("length",length);
        param.put("userId",userId);
        ArrayList<HashMap> list = userFileMapper.selectIndex(param);
        Long count = userFileMapper.selectFileCount(param);
        PageUtils pageUtils = new PageUtils(list,count,start,length);
        return new JsonResponseBody(ResponseStatus.SUCCESS,pageUtils);
    }

    /**
     * 文件id搜索
     * @param fileId
     * @return
     */
    @GetMapping("{id}")
    public JsonResponseBody searchFileById(@PathVariable("id") Integer fileId){
        UserFile userFile = userFileMapper.selectById(fileId);
        return new JsonResponseBody(ResponseStatus.SUCCESS,userFile);
    }
    @GetMapping("{filename}")
    public JsonResponseBody searchFileByName(@PathVariable("filename")String fileName){
        List<UserFileVO> userFileVOS = userFileMapper.selectByName(fileName);
        return new JsonResponseBody(ResponseStatus.SUCCESS,userFileVOS);
    }
    @GetMapping("download")
    public void downloadFile(HttpServletResponse response,Integer fileId) throws IOException {
        response.setHeader("Content-Type", "application/octet-stream");
        response.setContentType("application/octet-stream; charset=UTF-8");
        UserFile userFile = userFileMapper.selectById(fileId);
        System.out.println(userFile);
        String fileName = userFile.getFileName();
        fileName = new String(fileName.getBytes("UTF-8"),"ISO8859-1");
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        response.addHeader("Content-Length", "" + userFile.getFileSize());
        response.setContentType("application/force-download");
        File file = new File(userFile.getFilePath());
        InputStream inputStream = new FileInputStream(file);
        OutputStream outputStream = response.getOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while ((len = inputStream.read(buffer)) != -1){
            outputStream.write(buffer,0,len);
        }
        inputStream.close();
        outputStream.flush();
    }
    @DeleteMapping ("{fileId}")
    public JsonResponseBody deleteFile(@PathVariable("fileId")Integer fileId){
        UserFile userFile = userFileMapper.selectById(fileId);
        File file = new File(userFile.getFilePath());
        if (!file.isFile()){
            return new JsonResponseBody(ResponseStatus.DELETE_FAIL);
        }
        file.delete();
        userFileMapper.deleteById(fileId);
        return new JsonResponseBody(ResponseStatus.DELETE_SUCCESS);
    }
    /**
     * 文件分享功能
     */
    @GetMapping("share/{fileId}")
    public JsonResponseBody shareFile(@PathVariable("fileId") Integer fileId, HttpServletRequest request) {
        HttpSession session = request.getSession();
        UserFileVO fileVO = userFileMapper.selectByIdVO(fileId);
        if (fileVO == null) {
            return new JsonResponseBody(ResponseStatus.FILE_NOT_FOUND);
        }
        ShareFiles shareFiles= userFileMapper.getShareInfoByFileId(fileId);
        if(shareFiles==null){
            shareFiles=new ShareFiles();
            shareFiles.setShareFileId(fileVO.getFileId());
            shareFiles.setShareUserId(fileVO.getUserId());
            shareFiles.setShareState(0);
            shareFiles.setShareUrl("http://localhost:8080/filedetail.html?code="+new BASE64Encoder().encode((fileVO.getFileId()+"").getBytes(StandardCharsets.UTF_8)));
            userFileMapper.insertShareFiles(shareFiles);
        }
        fileVO.setUrl("分享地址为：【http://localhost:8080/filedetail.html?code="+new BASE64Encoder().encode((fileVO.getFileId()+"").getBytes(StandardCharsets.UTF_8))+"】");
        return new JsonResponseBody(ResponseStatus.SUCCESS,fileVO);
    }

    /**
     * 文件分享功能
     */
    @GetMapping("shareFileByPath/{code}")
    public JsonResponseBody shareFileByPath(@PathVariable("code") String code, HttpServletRequest request) throws IOException {
        UserFileVO fileVO = userFileMapper.selectByIdVO(Integer.parseInt(new String(new BASE64Decoder().decodeBuffer(code))));
        if (fileVO == null) {
            return new JsonResponseBody(ResponseStatus.FILE_NOT_FOUND);
        }
        return new JsonResponseBody(ResponseStatus.SUCCESS,fileVO);
    }

    /**
     * 文件批量删除
     */
    @DeleteMapping("/deleteFileByIds")
    public JsonResponseBody deleteFileByIds(@RequestBody DeleteFileByIdsDTO form){
        System.out.println(form.getIds());
        ArrayList<String> filePaths = userFileMapper.getFilePathsByIds(form.getIds());
        for (String filePath : filePaths) {
            File file = new File(filePath);
            if (!file.isFile()){
                return new JsonResponseBody(ResponseStatus.DELETE_FAIL);
            }
            file.delete();
        }
        int rows = userFileMapper.deleteFileByIds(form.getIds());
        return new JsonResponseBody(ResponseStatus.SUCCESS,rows);
    }
}
